package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.article.ArticleConstans;
import com.heima.article.feign.AdminFeign;
import com.heima.article.feign.BehaviorFeign;
import com.heima.article.feign.UserFeign;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.common.constans.message.MessageConstants;
import com.heima.model.admin.pojos.AdChannel;
import com.heima.model.article.dto.ArticleHomeDto;
import com.heima.model.article.dto.ArticleInfoDto;
import com.heima.model.article.pojos.*;
import com.heima.model.article.vo.HotArticleVo;
import com.heima.model.behavior.pojo.ApBehaviorEntry;
import com.heima.model.behavior.pojo.ApLikesBehavior;
import com.heima.model.behavior.pojo.ApUnlikesBehavior;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.media.dto.NewsDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.ApCollectionService;
import com.heima.article.service.AuthorService;
import com.heima.utils.threadlocal.ApUserThreadLocalUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {

    @Autowired
    ApArticleConfigServiceImpl articleConfigService;

    /**
     * 修改文章上下架，只用做feign远程调用，不对外暴露
     * @param dto
     * @return
     */
    @Override
    public ResponseResult downOrUp(NewsDto dto) {
        ApArticleConfig articleConfig = articleConfigService.getOne(Wrappers.<ApArticleConfig>lambdaQuery().eq(ApArticleConfig::getArticleId, dto.getId()));
        articleConfig.setIsDown(!articleConfig.getIsDown());
        articleConfigService.updateById(articleConfig);
        return null;
    }



    @Autowired
    ApArticleMapper apArticleMapper;
    /**
     * 根据条件查询
     * @param loadtype
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ApArticle>> load(short loadtype, ArticleHomeDto dto) {

        //1.检查参数
        if (dto==null){
          dto=new ArticleHomeDto();
          dto.setSize(10);
      }
      if (dto.getMaxBehotTime()==null){
          dto.setMaxBehotTime(new Date());
      }
      if (dto.getMinBehotTime()==null){
          dto.setMinBehotTime(new Date());
      }
      //校验频道
      if (dto.getTag()==null){
          dto.setTag(ArticleConstans.DEFAULT_TAG);
      }

        //对象查询条数进行限制（合理化）
      if (dto.getSize()>50){
            dto.setSize(50);
      }
      //要判断当前文章是否可查阅，需要判断  1.是否上架  2.判断是否已删除
        //需要查询多表`ap_article``ap_article_config`
        List<ApArticle> list = apArticleMapper.load(loadtype, dto);
      ResponseResult<List<ApArticle>> result=new PageResponseResult();
      result.setData(list);
        return result;
    }
   @Autowired
   AdminFeign adminFeign;

    /**
     * 查询热点文章,如果查询首页则查询所有，根据热点排序
     * @param loadtype
     * @param dto
     * @return
     */
    public ResponseResult<List<ApArticle>> load2(short loadtype, ArticleHomeDto dto) {
       if (dto==null){
           dto=new ArticleHomeDto();
           dto.setTag("_all_");
           Object o = redisTemplate.boundValueOps(ArticleConstans.HOT_ARTICLE_FIRST_PAGE + dto.getTag()).get();
           List<HotArticleVo> list = JSON.parseArray(o.toString(), HotArticleVo.class);
            //如果为null则查询数据库
           if(list!=null&&list.size()!=0){
               return ResponseResult.okResult(list);
           }

       }
        return load(loadtype,dto);
    }


    @Autowired
    ApArticleContentService articleContentService;

    @Override
    public ResponseResult findById(ArticleInfoDto dto) {

        //检查参数
        if (dto==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        Map<String,Object> map=new HashMap<>();
        //判断文章是否已上架，或删除
        ApArticleConfig articleConfig = articleConfigService.getById(Wrappers.<ApArticleConfig>lambdaQuery().eq(ApArticleConfig::getArticleId, dto.getArticleId()));

        ApArticleContent articleContent = articleContentService.getOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, dto.getArticleId()));
        if (!articleConfig.getIsDown()&&!articleConfig.getIsDelete()&&articleContent!=null){

            map.put("content",articleContent);
            map.put("config",articleConfig);
           return ResponseResult.okResult(map);
        }

        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
    }


    @Autowired
    ApCollectionService apCollectionService;

    @Autowired
    AuthorService authorService;

    @Autowired
    UserFeign userFeign;

    @Autowired
    BehaviorFeign behaviorFeign;
    /**
     * 查询文章相关信息
     * @param dto
     * @return
     */
    //{"isfollow":true,"islike":true,"isunlike":false,"iscollection":true}
    @Override
    public ResponseResult loadArticleBehavior(ArticleInfoDto dto) {
       //1.检查参数////
        if (dto==null||dto.getArticleId()==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2根据文章id获取作者id
        ApArticle article = getById(dto.getArticleId());
        if (article==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }


        //3.获取是否关注
        //3.1根据作者id获取作者用户id
        ApAuthor author = authorService.getById(article.getAuthorId());
        //3.2获取用户id
        ApUser user = ApUserThreadLocalUtils.getUser();
        if (user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE,"需要登录");
        }
       //3.3获取行为对象
        ApBehaviorEntry behaviorEntry = behaviorFeign.findByUserIdOrEquipmentId(user.getId(), null);
        if (behaviorEntry==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.SUCCESS,"暂无关注");
        }

        //3.4根据用户id和作者用户id查询follow表
        ApUserFollow userFollow = userFeign.getFollow(author.getUserId(), user.getId().longValue());//用户id为int有可能出错

        //根据文章id和实体id查询ap_collection
        ApCollection apCollection = apCollectionService.getOne(Wrappers.<ApCollection>lambdaQuery().eq(ApCollection::getArticleId, dto.getArticleId()).eq(ApCollection::getEntryId, behaviorEntry.getId()));

        //根据文章id和实体id查询`ap_likes_behavior
        ApLikesBehavior likesBehavior = behaviorFeign.getlike(behaviorEntry.getId(), dto.getArticleId());
        //根据文章id和实体id查询ap_unlikes_behavior
        ApUnlikesBehavior unlikesBehavior = behaviorFeign.getUnlike(behaviorEntry.getId(), dto.getArticleId());

        //封装数据
//{"isfollow":true,"islike":true,"isunlike":false,"iscollection":true}
        Boolean isfollow=false;
        Boolean islike=false;
        Boolean isunlike=false;
        Boolean iscollection=false;

        if (userFollow!=null){
            isfollow=true;
        }
        if (apCollection!=null){
            iscollection=true;
        }
        if (likesBehavior!=null&&likesBehavior.getOperation().shortValue()==0){
            islike=true;
        }
        if (unlikesBehavior!=null&&unlikesBehavior.getType()==0){
            isunlike=true;
        }
        HashMap<String,Boolean> map=new HashMap<>();
        map.put("isfollow",isfollow);
        map.put("iscollection",iscollection);
        map.put("islike",islike);
        map.put("isunlike",isunlike);
        //返回结果
        return ResponseResult.okResult(map);
    }

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    AdminFeign adminFeign;
    /**
     * 热门文章计算
     */
    @Override
    public void computeHotArticle() {
        //1.查询频道
        ResponseResult<List<AdChannel>> result = adminFeign.getAll();
        if (result.getCode()!=AppHttpCodeEnum.SUCCESS.getCode()||result.getData()==null){
            return;
        }
        //2.查询热点文章
        List<AdChannel> data = result.getData();
        for (AdChannel datum : data) {
            //2.1查询前五天
            //2.2文章上下架为0，删除状态为0，
            //2.3查询每个频道的前30条

            List<Map<String, Object>> maps = apArticleMapper.computeHotArticle(datum.getId(), getDate(), 30);
            //存入redis
            redisTemplate.boundValueOps(ArticleConstans.HOT_ARTICLE_FIRST_PAGE+datum.getId()).set(JSON.toJSONString(maps));

        }



    }

    //计算前五天时间
    private Date getDate() {
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.DAY_OF_YEAR,instance.get(Calendar.DAY_OF_YEAR)-5);
        instance.set(Calendar.HOUR_OF_DAY,1);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.SECOND,0);
        return instance.getTime();
    }
}